'''
Created on 2014-2-4

@author: apple
'''
# from django.http.response import HttpResponse #for version 1.5
from django.http import HttpResponse #for version 1.4
from datetime import datetime, timedelta
from django.conf import settings
import json
import sys
import logging
from types import *
from django.utils.timezone import pytz, UTC
from django.utils import timezone
from mongoengine.errors import DoesNotExist




logger = logging.getLogger("Sword")


def template(name, dic=None):
    from django.shortcuts import render_to_response
    if not dic:
        dic={}
    return render_to_response(name, dic)


class RequiredArgMissed(Exception):
    def __init__(self, name):
        self.name = name

class IPAddressNotAllowed(Exception):
    pass



def error_msg(code = -1, msg = "", arg = None):
    if arg:
        return {"status": code, "message": unicode( msg % arg)}
    else:
        return {"status": code, "message": unicode( msg)}


def message(msg = "", arg = None):
    if arg:
        return error_msg(0,  unicode(msg % arg))
    else:
        return error_msg(0, unicode(msg))

def tab2json(request, tab):
    response = None
    cb = request.REQUEST.get('__callback', None)
    if cb:
        response = HttpResponse(mimetype = "text/html")
        response.write("""
        <script type="text/javascript">
           %s(""" % cb)
    else:
        response = HttpResponse(mimetype = "application/json")
    response.write(json.dumps(tab))
    #chinese encode in windows
    #response.write(json.dumps(tab, ensure_ascii=False))
    if cb:
        response.write(""")
        </script>
        """)
    return response;

def handle_except(fn):
    def handler(request):
        try:
            return fn(request)
        except:
            if settings.DEBUG:
                raise
            else:
                return tab2json(request,error_msg(msg="Some error happened on server"))

    return handler

def tojson(fn):
    @handle_except
    def json_encode(request):
        return tab2json(request, fn(request))

    return json_encode

def from_local(fn):
    def check(request):
        client_ip = request.META.get('REMOTE_ADDR')
        if client_ip != "127.0.0.1":
            return error_msg(msg="Permission denied")
        else:
            return fn(request)

    return check

def ip_address_allowed(request):
    try:
        client_ip = request.META.get('REMOTE_ADDR')
        for ip in request.session.get('allowed_ip', ['*']):
            if ip == '*' or ip == client_ip:
                return
        raise IPAddressNotAllowed()
    except KeyError:
        pass
    else:
        raise

def check_ip(fn):
    def check(request):
        try:
            return fn(request)
        except IPAddressNotAllowed:
            return error_msg(msg = "Not allowed from your IP address")
        else:
            return error_msg(msg = "Internal server error")
    return check

def check_login(fn):
    @check_ip
    def check(request):
        if request.session.get('user_id', None):
            ip_address_allowed(request)
            return fn(request)
        else:
            return error_msg(msg="Please login first")

    return check

def check_permission(perm):
    PERMISSIONS = {
            "Administrator": 0,
            "Operator": 1,
            "Viewer": 2
    }

    def real_check(fn):
        @check_login
        def check(request):
            required = PERMISSIONS.get(perm, 0)
            owned = PERMISSIONS.get(request.session['permission'], sys.maxint)

            if required >= owned:
                return fn(request)
            else:
                return error_msg(msg="Permission denied")
        return check
    return real_check


def get_required_argument(request, name):
    try:
        return request.REQUEST[name]
    except KeyError:
        raise RequiredArgMissed(name)
    else:
        raise

def check_required_argument(fn):
    def check(request):
        try:
            return fn(request)
        except RequiredArgMissed as e:
            return error_msg(msg="%s required", arg = e.name)
        else:
            return error_msg(msg = "Internal server error")
    return check

def string_ifilter(request, qs, filters):
    f = {}
    for k in filters:
        s = request.REQUEST.get(k, None)
        if s and s != "":
            f[k + "__icontains"] = s
    if len(f) > 0:
        return qs.filter(**f)
    else:
        return qs
    
def string_in_filter(request, qs, filters):
    f = {}
    for k in filters:
        s = request.REQUEST.get(k, None)
        if s and s != "":
            f[k + "__in"] = s.split(",")
    if len(f) > 0:
        return qs.filter(**f)
    else:
        return qs

def str2time(str):
    return datetime.strptime(str, "%Y-%m-%d %H:%M:%S")
    
def time2str(t):
    if isinstance(t, datetime):
        return t.strftime("%Y-%m-%d %H:%M:%S")
    else:
        return ""
def utctime2local(t):
    from django.utils import timezone
    if timezone.is_naive(t):
        t = timezone.make_aware(t, timezone.utc)
    return timezone.localtime(t)    
    
def utctime2str(t):
    return time2str(utctime2local(t))
    
def time_filter(request, qs, filters):
    f = {}
    for k in filters:
        s = request.REQUEST.get(k + "__from", None)
        if s and s != "":
            f[k + "__gte"] = str2time(s)
        s = request.REQUEST.get(k + "__to", None)
        if s and s != "":
            f[k + "__lte"] = str2time(s)

    if len(f) > 0:
        return qs.filter(**f)
    else:
        return qs

def sort(request, qs, default="-id"):
    s = request.REQUEST.get("__sort", default)
    if s:
        return qs.order_by(s)
    else:
        return qs




def random_str(input):
    import uuid
    import hashlib

    r = uuid.uuid4()
    sha = hashlib.sha1()
    sha.update(unicode(r))
    sha.update(unicode(datetime.now()))
    if input:
        sha.update(unicode(input))
        
    return sha.hexdigest()



def get_config(name, default_val = None):
    from com.ad.sword.dao.models import SystemConfig
    try:
        sc = SystemConfig.objects.get(name=name)
        return unicode(sc.value)
    except DoesNotExist:
        return default_val

def get_int_config(name, default_val=0):
    val = get_config(name)
    if val:
        return int(val)
    else:
        return default_val

def get_remote_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

